#include "service/chat/chat_service.h"
#include "database/mysql_pool.h"
#include "cache/redis_client.h"
#include "messaging/kafka_producer.h"
#include "messaging/kafka_consumer.h"
#include "common/logger/logger.h"
#include <iostream>
#include <fstream>
#include <nlohmann/json.hpp>
#include <csignal>
#include <thread>
#include <chrono>

using namespace common::logger;

// 全局聊天服务指针，用于信号处理
std::shared_ptr<service::chat::ChatService> g_chatService;

// 信号处理函数
void signalHandler(int signum) {
    LOG_INFO("接收到信号: " + std::to_string(signum));
    if (g_chatService) {
        LOG_INFO("正在停止聊天服务...");
        g_chatService->stop();
    }
    exit(signum);
}

// 加载配置文件
bool loadConfig(const std::string& configFile, nlohmann::json& config) {
    std::ifstream file(configFile);
    if (!file.is_open()) {
        LOG_ERROR("无法打开配置文件: " + configFile);
        return false;
    }

    try {
        file >> config;
        return true;
    } catch (const nlohmann::json::parse_error& e) {
        LOG_ERROR("解析配置文件失败: " + std::string(e.what()));
        return false;
    }
}

bool findAndLoadConfig(const std::string& configFileName, nlohmann::json& config) {
    // 尝试多个可能的位置
    std::vector<std::string> possiblePaths = {
            configFileName,                    // 直接使用提供的路径
            "config/" + configFileName,        // 相对于当前目录的config子目录
            "../config/" + configFileName,     // 上级目录的config
            "../../config/" + configFileName,  // 上上级目录的config
            "../../../config/" + configFileName // 上上上级目录的config
    };

    for (const auto& path : possiblePaths) {
        std::cout << "尝试加载配置文件: " << path << std::endl;
        if (loadConfig(path, config)) {
            std::cout << "成功加载配置文件: " << path << std::endl;
            return true;
        }
    }

    std::cerr << "无法在任何位置找到配置文件: " << configFileName << std::endl;
    return false;
}

int main(int argc, char* argv[]) {
    // 初始化日志系统
    Logger::getInstance().setLevel(LogLevel::INFO);
    
    // 添加文件日志
    try {
        std::shared_ptr<LogSink> fileSink = std::make_shared<FileSink>("chat_service.log");
        Logger::getInstance().addSink(fileSink);
        Logger::getInstance().startAsync();
    } catch (const std::exception& e) {
        std::cerr << "初始化日志失败: " << e.what() << std::endl;
    }
    
    LOG_INFO("聊天服务启动中...");

    // 注册信号处理函数
    signal(SIGINT, signalHandler);
    signal(SIGTERM, signalHandler);

    // 默认配置文件路径
    std::string configFile = "chat_service.json";

    // 如果命令行指定了配置文件，则使用指定的配置文件
    if (argc > 1) {
        configFile = argv[1];
    }

    // 加载配置
    nlohmann::json config;
    if (!findAndLoadConfig(configFile, config)) {
        LOG_FATAL("加载配置文件失败");
        return 1;
    }

    try {
        // 获取配置项
        int port = config.value("port", 8002);
        
        // 数据库配置
        std::string dbHost = config["database"].value("host", "localhost");
        std::string dbUser = config["database"].value("user", "root");
        std::string dbPassword = config["database"].value("password", "");
        std::string dbName = config["database"].value("database", "chat_system");
        int dbPort = config["database"].value("port", 3306);
        int dbPoolSize = config["database"].value("pool_size", 10);

        // Redis配置
        std::string redisHost = config["redis"].value("host", "localhost");
        int redisPort = config["redis"].value("port", 6379);
        std::string redisPassword = config["redis"].value("password", "");
        int redisDb = config["redis"].value("db", 0);
        int redisPoolSize = config["redis"].value("pool_size", 5);

        // 创建数据库连接池
        auto dbPool = database::MySQLPool::create(
            dbHost, dbUser, dbPassword, dbName, dbPort, dbPoolSize);

        if (!dbPool) {
            LOG_FATAL("创建MySQL连接池失败");
            return 1;
        }

        // 创建Redis连接池和客户端
        cache::RedisConfig redisConfig;
        redisConfig.host = redisHost;
        redisConfig.port = redisPort;
        redisConfig.password = redisPassword;
        redisConfig.db = redisDb;
        redisConfig.poolSize = redisPoolSize;

        auto redisPool = cache::RedisPool::create(redisConfig);
        if (!redisPool) {
            LOG_FATAL("创建Redis连接池失败");
            return 1;
        }

        auto redisClient = std::make_shared<cache::RedisClient>(redisPool);
        
        // Kafka配置
        std::shared_ptr<messaging::KafkaProducer> kafkaProducer;
        std::shared_ptr<messaging::KafkaConsumer> kafkaConsumer;
        
        // 尝试加载Kafka配置
        nlohmann::json kafkaConfig;
        if (findAndLoadConfig("kafka.json", kafkaConfig)) {
            LOG_INFO("成功加载Kafka配置");
            
            // 创建Kafka生产者
            messaging::KafkaProducerConfig producerConfig;
            
            if (kafkaConfig.contains("kafka") && kafkaConfig["kafka"].contains("brokers")) {
                producerConfig.brokers = kafkaConfig["kafka"]["brokers"];
                
                if (kafkaConfig["kafka"].contains("producer")) {
                    const auto& prodConf = kafkaConfig["kafka"]["producer"];
                    if (prodConf.contains("clientId")) producerConfig.clientId = prodConf["clientId"];
                    if (prodConf.contains("timeoutMs")) producerConfig.timeoutMs = prodConf["timeoutMs"];
                    if (prodConf.contains("queueBufferingMaxMs")) producerConfig.queueBufferingMaxMs = prodConf["queueBufferingMaxMs"];
                    if (prodConf.contains("queueBufferingMaxMessages")) producerConfig.queueBufferingMaxMessages = prodConf["queueBufferingMaxMessages"];
                    if (prodConf.contains("queueBufferingMaxKbytes")) producerConfig.queueBufferingMaxKbytes = prodConf["queueBufferingMaxKbytes"];
                    if (prodConf.contains("requestRequiredAcks")) producerConfig.requestRequiredAcks = prodConf["requestRequiredAcks"];
                }
                
                kafkaProducer = messaging::KafkaProducer::create(producerConfig);
                if (!kafkaProducer) {
                    LOG_ERROR("创建Kafka生产者失败，将不使用Kafka功能");
                } else {
                    LOG_INFO("Kafka生产者创建成功");
                    
                    // 创建Kafka消费者
                    messaging::KafkaConsumerConfig consumerConfig;
                    consumerConfig.brokers = kafkaConfig["kafka"]["brokers"];
                    
                    if (kafkaConfig["kafka"].contains("consumer")) {
                        const auto& consConf = kafkaConfig["kafka"]["consumer"];
                        if (consConf.contains("groupId")) consumerConfig.groupId = consConf["groupId"];
                        if (consConf.contains("clientId")) consumerConfig.clientId = consConf["clientId"];
                        if (consConf.contains("sessionTimeoutMs")) consumerConfig.sessionTimeoutMs = consConf["sessionTimeoutMs"];
                        if (consConf.contains("maxPollIntervalMs")) consumerConfig.maxPollIntervalMs = consConf["maxPollIntervalMs"];
                        if (consConf.contains("offsetReset")) consumerConfig.offsetReset = consConf["offsetReset"];
                        if (consConf.contains("fetchMaxBytes")) consumerConfig.fetchMaxBytes = consConf["fetchMaxBytes"];
                        if (consConf.contains("fetchMaxWaitMs")) consumerConfig.fetchMaxWaitMs = consConf["fetchMaxWaitMs"];
                    }
                    
                    kafkaConsumer = messaging::KafkaConsumer::create(consumerConfig);
                    if (!kafkaConsumer) {
                        LOG_ERROR("创建Kafka消费者失败，将不使用Kafka消费功能");
                    } else {
                        LOG_INFO("Kafka消费者创建成功");
                    }
                }
            }
        } else {
            LOG_WARNING("未找到Kafka配置，将不使用Kafka功能");
        }

        // 创建聊天服务
        g_chatService = service::chat::ChatService::create(dbPool, redisClient, kafkaProducer, kafkaConsumer);
        if (!g_chatService) {
            LOG_FATAL("创建聊天服务失败");
            return 1;
        }

        // 启动服务
        LOG_INFO("聊天服务正在启动，监听端口: " + std::to_string(port));
        if (!g_chatService->start(port)) {
            LOG_FATAL("启动聊天服务失败");
            return 1;
        }

        // 主线程保持运行
        while (true) {
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }
    } catch (const std::exception& e) {
        LOG_FATAL("服务异常: " + std::string(e.what()));
        return 1;
    }

    return 0;
} 